package com.centriole.service.workflow.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.text.SimpleDateFormat;

public class JSONHelper {
	 private static ObjectMapper MAPPER;

	    static {
	        MAPPER = new ObjectMapper();
	    }

	    private JSONHelper() {
	    }

	    /**
	     * 将json通过类型转换成对象
	     * <p/>
	     * <pre>
	     *     {@link JSONHelper JsonUtil}.fromJson("{\"username\":\"username\", \"password\":\"password\"}", User.class);
	     * </pre>
	     *
	     * @param json  json字符串
	     * @param clazz 泛型类型
	     * @return 返回对象
	     * @throws IOException
	     */
	    public static <T> T fromJson(String json, Class<T> clazz) throws IOException {
	        if (null == json || json.equals("")) {
	            return null;
	        } else {
	            return clazz.equals(String.class) ? (T) json : MAPPER.readValue(json, clazz);
	        }
	    }

	    /**
	     * 将json通过类型转换成集合对象
	     * <p/>
	     * <pre>
	     *     {@link JSONHelper JsonUtil}.fromJson("[{\"username\":\"username\", \"password\":\"password\"}, {\"username\":\"username\", \"password\":\"password\"}]", new TypeReference<List<User>>);
	     * </pre>
	     *
	     * @param json          json字符串
	     * @param typeReference 引用类型
	     * @return 返回对象
	     * @throws IOException
	     */
	    public static <T> T fromJson(String json, TypeReference<?> typeReference) throws IOException {
	        if (null == json || json.equals("")) {
	            return null;
	        } else {
	            return (T) (typeReference.getType().equals(String.class) ? json : MAPPER.readValue(json, typeReference));
	        }
	    }

	    /**
	     * 将对象转换成json
	     * <p/>
	     * <pre>
	     *     {@link JSONHelper JsonUtil}.toJson(user);
	     * </pre>
	     *
	     * @param src 对象
	     * @return 返回json字符串
	     * @throws IOException
	     */
	    public static <T> String toJson(T src) throws IOException {
	        return src instanceof String ? (String) src : MAPPER.writeValueAsString(src);
	    }

	    /**
	     * 将对象转换成json, 可以设置输出属性
	     * <p/>
	     * <pre>
	     *     {@link JSONHelper JsonUtil}.toJson(user, {@link JsonInclude Inclusion.ALWAYS});
	     * </pre>
	     * <p/>
	     * {@link JsonInclude Inclusion 对象枚举}
	     * <ul>
	     * <li>{@link JsonInclude.Include ALWAYS 全部列入}</li>
	     * <li>{@link JsonInclude.Include NON_DEFAULT 字段和对象默认值相同的时候不会列入}</li>
	     * <li>{@link JsonInclude.Include NON_EMPTY 字段为NULL或者""的时候不会列入}</li>
	     * <li>{@link JsonInclude.Include NON_NULL 字段为NULL时候不会列入}</li>
	     * </ul>
	     *
	     * @param src       对象
	     * @param inclusion 传入一个枚举值, 设置输出属性
	     * @return 返回json字符串
	     * @throws IOException
	     */
	    public static <T> String toJson(T src, JsonInclude.Include inclusion) throws IOException {
	        if (src instanceof String) {
	            return (String) src;
	        } else {
	            ObjectMapper customMapper = new ObjectMapper();
	            customMapper.setSerializationInclusion(inclusion);
	            return customMapper.writeValueAsString(src);
	        }
	    }

	    /**
	     * 将对象转换成json, 传入配置对象
	     * <p/>
	     * <pre>
	     *     {@link ObjectMapper ObjectMapper} mapper = new ObjectMapper();
	     *     mapper.setSerializationInclusion({@link JsonInclude.Include ALWAYS});
	     *     mapper.configure({@link DeserializationFeature FAIL_ON_UNKNOWN_PROPERTIES}, false);
	     *     mapper.configure({@link DeserializationFeature FAIL_ON_NUMBERS_FOR_ENUMS}, true);
	     *     mapper.setDateFormat(new {@link SimpleDateFormat SimpleDateFormat}("yyyy-MM-dd HH:mm:ss"));
	     *     {@link JSONHelper JsonUtil}.toJson(user, mapper);
	     * </pre>
	     * <p/>
	     * {@link ObjectMapper ObjectMapper}
	     *
	     * @param src    对象
	     * @param mapper 配置对象
	     * @return 返回json字符串
	     * @throws IOException
	     * @see ObjectMapper
	     */
	    public static <T> String toJson(T src, ObjectMapper mapper) throws IOException {
	        if (null != mapper) {
	            if (src instanceof String) {
	                return (String) src;
	            } else {
	                return mapper.writeValueAsString(src);
	            }
	        } else {
	            return null;
	        }
	    }

	    /**
	     * 返回{@link ObjectMapper ObjectMapper}对象, 用于定制性的操作
	     *
	     * @return {@link ObjectMapper ObjectMapper}对象
	     */
	    public static ObjectMapper mapper() {
	        return MAPPER;
	    }
}
